package com.pe.pgn.clubpgn.webapp.controller.almacen;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.support.SessionStatus;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.domain.ClpbAlmacen;
import com.pe.pgn.clubpgn.domain.ClpbEstacion;
import com.pe.pgn.clubpgn.domain.ClpmUbigeo;
import com.pe.pgn.clubpgn.service.AlmacenService;
import com.pe.pgn.clubpgn.service.EstacionService;
import com.pe.pgn.clubpgn.service.UbigeoService;
import com.pe.pgn.clubpgn.webapp.controller.BaseFormController;

@Controller
@RequestMapping("/almacen/**")
public class AlmacenController extends BaseFormController {

	@Autowired
	private AlmacenService almacenService;
	
	@Autowired
	private EstacionService estacionService;
	
	@Autowired
	private UbigeoService ubigeoService;
	
	private static final String ES_EDITABLE = "esEditable";
	
	@RequestMapping(value = "/almacenlist.html")
    public void listarArticulos(Model model) {
		
		List<ClpbAlmacen> almacenes = almacenService.obtenerAlmacenes(Boolean.TRUE);
		List<ClpbEstacion> estaciones = estacionService.obtenerEstaciones();
		
		model.addAttribute("almacenes", almacenes);
		model.addAttribute("estaciones", estaciones);
	}
	
	@RequestMapping(value = "/almacenform.html", method = RequestMethod.GET)
	public @ModelAttribute("almacen") ClpbAlmacen verAlmacen(
				@RequestParam(value = "id", required = false) Long id, Model model) {

		ClpbAlmacen almacen = new ClpbAlmacen();
		if (id != null) {			
			
			almacen = almacenService.obtenerAlmacen(id);
			boolean almacenConDependencias = almacenService.esAlmacenConDependencias(id);			
			if(almacenConDependencias){
				model.addAttribute(ES_EDITABLE, Boolean.FALSE);	
			}
			else{				
				
				List<ClpbEstacion> estaciones = estacionService.obtenerEstaciones();
				model.addAttribute("estaciones", estaciones);				
				model.addAttribute(ES_EDITABLE, Boolean.TRUE);				
				model = asignarListasUbigeos(model);		
			}					
			return almacen;
		}
		
		asignarVariablesComunes(model, almacen);				
		almacen.setStAlmacen(Boolean.TRUE);
		almacen.setStEsPuntoCanje(Boolean.TRUE);		
		return almacen;
	}
	
	@RequestMapping(value = "/almacenform.html", method = RequestMethod.POST)
	public String guardarAlmacen(@ModelAttribute("almacen") ClpbAlmacen almacen,
			BindingResult result, SessionStatus status, HttpServletRequest request, Model model) {
		
		try{
			
			boolean esAlmacenValido = esAlmacenValido(almacen, request, model);						
			if (result.hasErrors() || !esAlmacenValido) {				
				return asignarVariablesComunes(model, almacen);
			}
			
			almacenService.guardarAlmacen(almacen);
			saveMessage(request, getText("almacenform.added", almacen.getDeAlmacen().length() > CLPConstantes.LIMITE_CADENA ?
					almacen.getDeAlmacen().substring(0, CLPConstantes.LIMITE_CADENA)
					.concat(CLPConstantes.PUNTOS_SUSPENSIVOS) : almacen.getDeAlmacen(), 
					request.getLocale()));
			return "redirect:almacenform.html?from=list&id="+almacen.getId();
			
		}catch (Exception e) {
			saveError(request, getText("errors.general", request.getLocale()));

			boolean almacenConDependencias = almacenService.esAlmacenConDependencias(almacen.getId());			
			if(almacenConDependencias){
				model.addAttribute(ES_EDITABLE, Boolean.FALSE);	
			}
			else{				
				
				List<ClpbEstacion> estaciones = estacionService.obtenerEstaciones();
				model.addAttribute("estaciones", estaciones);				
				model.addAttribute(ES_EDITABLE, Boolean.TRUE);				
				model = asignarListasUbigeos(model);		
			}		
			
			ClpmUbigeo ubigeo = ubigeoService.obtenerUbigeo(almacen.getClpmUbigeo().getId());
			almacen.setClpmUbigeo(ubigeo);
			model.addAttribute("almacen", almacen);		
			return "/almacen/almacenform";
		}		
	}
	
	@RequestMapping(value = "/eliminaralmacen.html")
	public String eliminarAlmacen(@RequestParam(value = "id", required = false) Long id, 
			HttpServletRequest request, Model model) {
		
		try {			
				
			almacenService.eliminarAlmacen(id);
			saveMessage(request, getText("almacenform.deleted", request.getLocale()));
			return "redirect:almacenlist.html";
			
		} catch (Exception e) {
			saveError(request, getText("errors.general", request.getLocale()));
			return "redirect:almacenform.html?from=list&id="+id;
			
		}
	}
	
	public Model asignarListasUbigeos(Model model){
		
		List<Map<String, Object>> departamentos = ubigeoService.obtenerDepartamentos(Boolean.TRUE);
		model.addAttribute("departamentos", departamentos);
				
		Map<String, Object> departamento = departamentos.get(0);
		BigDecimal coDepartamento = (BigDecimal)departamento.get("coDepartamento");
		List<Map<String, Object>> provincias = ubigeoService.obtenerProvinciasPorDepartamento(Boolean.TRUE, coDepartamento);
		model.addAttribute("provincias", provincias);
		
		Map<String, Object> provincia = provincias.get(0);
		BigDecimal coProvincia = (BigDecimal)provincia.get("coProvincia");
		List<Map<String, Object>> distritos = ubigeoService.obtenerDistritosPorProvincia(coDepartamento, coProvincia);
		model.addAttribute("distritos", distritos);
		
		return model;
	}
	
	public boolean esAlmacenValido(ClpbAlmacen almacen, HttpServletRequest request, Model model){
		
		if(almacen.isStEsAlmacenPrincipal()){				
			boolean existeAlmacenPrincipal = almacenService.existeAlmacenPrincipal(almacen.getId());
			if(existeAlmacenPrincipal){
				model.addAttribute("almacen", almacen);
				saveError(request, getText("almacenform.error.existe.almacen.principal", request.getLocale()));
				return false;
			}
		}
		else if(almacen.isStEsAlmacenVirtual()){
			
			boolean existeAlmacenVirtual = almacenService.existeAlmacenVirtual(almacen.getId());
			if(existeAlmacenVirtual){
				model.addAttribute("almacen", almacen);
				saveError(request, getText("almacenform.error.existe.almacen.virtual", request.getLocale()));
				return false;
			}
		}
		
		boolean esEstacionUsada = almacenService.esEstacionUsada(almacen.getClpbEstacion().getId(), almacen.getId());
		if(esEstacionUsada){
			model.addAttribute("almacen", almacen);
			saveError(request, getText("almacenform.error.estacion.usada", request.getLocale()));
			return false;
		}
		
		return true;
	}
	
	public String asignarVariablesComunes(Model model, ClpbAlmacen almacen){
		
		model.addAttribute("almacen", almacen);					
		if(almacen.getId() != null){
			return "redirect:almacenform.html?id="+almacen.getId();
		}
		else{
			List<ClpbEstacion> estaciones = estacionService.obtenerEstaciones();
			model.addAttribute("estaciones", estaciones);
			
			model.addAttribute(ES_EDITABLE, Boolean.TRUE);	
			
			model = asignarListasUbigeos(model);	
			return "/almacen/almacenform";
		}	
	}	
}
